home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 338_01 / as68.c < prev    next >
Text File  |  1989-11-29  |  9KB  |  286 lines

  1. /* as68.c, the source of a 68000 assembler.... (root)
  2.  *    (C) Copyright 1982 Steve Passe
  3.  *    All Rights Reserved
  4.  * 
  5.  *  ver. 1.00
  6.  * created 10/7/82
  7.  * 
  8.  * version 1.01
  9.  *
  10.  *   8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
  11.  *   12/23/83    fixed 24 bit address bug in flush_rcrd smp
  12.  *   12/24/83    fixed lowercase    a-f in S-records smp
  13.  *
  14.  * Oct-87 srd - fix 'char' - smp assumed chars were UNSIGNED - ha ha.
  15.  *    Also, fix numerous bugs and break into overlays for small
  16.  *    machines (like PDP-11, Whitesmith's compiler in particular)
  17.  *    This version works on both IBM-PC (Microsoft C vers 4.0) and
  18.  *    PDP-11 (TSX+, Whitesmith's RT-11 compiler). Seems solid.
  19.  *    I am beginning to understand how it works...
  20.  *        -Stuart R Dole, SAMKHYA Corp, 707-763-2800
  21.  */
  22.  
  23. /* begincode */
  24.  
  25. /* includes */
  26.  
  27. #include <stdio.h>
  28. #include "as68.h"
  29.  
  30. /* externals */
  31.  
  32. struct _symbol *symtbl = {0};
  33. struct _symbol *syms_head = {0};    /* head of sym table free space */
  34. char *syms_tail = NULL;            /* tail of sym table free space */
  35. int symspace = SYMTSIZE;        /* bytes in symbol table */
  36. int symbols = 0;            /* number of symbols in table */
  37.  
  38. FLAG fatal = NO;
  39. char pass = 1;              /* present pass number, 1 or 2 */
  40. unsigned line_count = 0;        /* line number of source file */
  41. unsigned list_count = 0;        /* line # of list file */
  42. long loc_counter = 0;           /* address to assemble obj code */
  43. int loc_plus = 0;            /* increment to loc counter    */
  44. char lcksm = 0;            /* bytes + addr. + count + lcksm == 0xff */
  45. FLAG abs_long = YES;            /* default to absolute long add.*/
  46. FLAG rorg = NO;             /* prog. counter relative flag */
  47. FLAG do_label = YES;            /* process label if set */
  48. char statement[STMNT_SIZE] = {0};    /* statement line buffer */
  49. char label[32] = {0};            /* bufr for label from preparse */
  50. char instr[32] = {0};            /* bufr for mnem, psdo or macro */
  51. char *opfld_ptr = NULL;            /* pointer to operand field */
  52. char stnt_typ = 0;            /* statement type, instr, pseudo */
  53. int wrap = 80;              /* wrap column for list output */
  54. FLAG trunc = NO;            /* truncate lines in listing */
  55. char source_name[FNAME_SIZE] = {0};    /* source file name */
  56. int src_level = 0;            /* source file level */
  57. FILE *_src[SRCLEVELS] = {0};        /* source file descripters */
  58. FLAG objchnl = 's';            /* Motorola S ('s') or nil ('x') */
  59. FLAG obj_open = NO;            /* object channel open flag */
  60. char of_disk = NULL;            /* default object file drive */
  61. char object_name[FNAME_SIZE] = {0};    /* object file name */
  62. FILE *obj_f = NULL;            /* object file descripter */
  63. FLAG lstchnl = NO;            /* list channel(s) open */
  64. FLAG nolist = NO;            /* flag for list/nolist pseudos */
  65. FLAG lcon = NO;             /* list to console flag */
  66. FLAG llst = NO;             /* list to list device flag */
  67. FLAG lfile = NO;            /* list to file flag */
  68. FLAG lfile_open    = NO;           /* list file open flag */
  69. char lf_disk = NULL;            /* default list file drive */
  70. char list_name[FNAME_SIZE] = {0};    /* listing file name */
  71. FILE *lst_f = NULL, *lst_d = NULL;    /* listing file & dev descripter */
  72. FLAG errchnl = YES;            /* error channel(s) open */
  73. FLAG econ = YES;            /* errors to console flag */
  74. FLAG elst = NO;             /* errors to list device flag */
  75. FLAG elfile = NO;            /* errors to listing file */
  76. FLAG efile = NO;            /* errors to error file */
  77. FLAG efile_open    = NO;           /* error file open flag */
  78. char ef_disk = NULL;            /* default error file drive */
  79. char error_name[FNAME_SIZE] = {0};    /* error file name */
  80. FILE *err_f = NULL;            /* error file descripter */
  81. struct _oprnd op1 = {0}, op2 = {0};    /* structs to hold operand val */
  82. char code[12] = {0};            /* 12 minimum for overflow */
  83. char buf[85] = {0};
  84. long lex_val = 0L;
  85. char *p = NULL;
  86.  
  87. extern struct _mtable mtable[];
  88.  
  89. /* things that were 'static' in overlays... */
  90.  
  91. FLAG any_errors = NO;
  92. int err_stk[MAXERR] = {0};    /* these two used to be 'static', moved to */
  93. int err_sp = MAXERR;        /*  root for overlay purposes */
  94. char *stmnt_ptr = NULL;    /* from ASETC.C, fcn obj_out */
  95. long s_lc = 0L;
  96. char s_buf[48] = "S";    /* init first character */
  97. int s_cnt = 0;        /* bytes in s_buf */
  98. int s_x = 0;        /* index into s_buf */
  99.  
  100. /* types */
  101.  
  102. char *nextfield();
  103. struct _mtable *mnemsearch();
  104. struct _ptable *psdosearch();
  105.  
  106. /* beginmain */
  107.  
  108. main(argc, argv)
  109. int argc;
  110. char *argv[];
  111. {
  112.     register struct _ptable *pt;    /* function    ptr returned by psdosearch */
  113.     register struct _mtable *mt;    /* function    ptr returned by mnemsearch */
  114.  
  115.     if (asinit(argc, argv)) {    /*************** start pass loop... */
  116.  
  117.     while (nextline()) {
  118.  
  119. /* parse line for label, instruction and operand field pointer */
  120.  
  121.     if (preparse() == COMMENT) {
  122.         if (pass == 2) dump_code(MSG, code, 0);    /* dump the line */
  123.         continue;
  124.     }
  125.     if (instr[0]) {     /*  mnemonic/pseudo-op/macro field is present) */
  126.         if (instr[31] && (pass == 2)) err_out(BAD_INSTR);
  127.                             /* check for mnemonic */
  128.         if (mt = mnemsearch(instr))    {
  129.         stnt_typ = MNEMONIC;
  130.         pass == 1 ? p1_mnem(mt)    : p2_mnem(mt);
  131.         }
  132.                             /* or pseudo-op */
  133.         else if (pt = psdosearch(instr)) {
  134.         stnt_typ = PSEUDO;        /* record the fact */
  135.         switch (pass) {
  136.         case 1:
  137.             (*pt->_p1)(pt->_psdo, pt->_arg);
  138.             if (pass == 2) continue;
  139.             break;
  140.         case 2:
  141.             (*pt->_p2)(pt->_psdo, pt->_arg);
  142.             if (pass == 3) goto finish;
  143.         }
  144.         }
  145.                         /** or macro use */
  146.         else if (FALSE /** macros not used yet **/) {
  147.             /** MACROS NOT IMPLIMENTED in version 1.xx */
  148.             stnt_typ = MACRO;
  149.         }
  150.         else {
  151.         stnt_typ = NULL;
  152.         err_out(UNREC_INSTR);
  153.         dump_code (CODE, code, 0);
  154.         }
  155.     }
  156.     else {
  157.         if (pass == 2) {
  158.         dump_code (CODE, code, 0);    /* label only line ? */
  159.         }
  160.     }
  161.  
  162.     if (label[0] && do_label) {
  163.         label_do();
  164.     }
  165.     do_label = YES;             /* reset for next line */
  166.     loc_counter += loc_plus;        /* update loc_counter */
  167.     loc_plus = NULL;            /* clear for next instruction */
  168.     if (fatal) {                /* fatal system ERROR */
  169.         puts("\007\nFATAL SYSTEM ERROR!\007");
  170.         break;
  171.     }
  172.     }                       /* end of pass loop */
  173.     } /* endif(asinit()) */
  174.  
  175. /** close shop... */
  176. finish: 
  177.     finis();
  178. }
  179.  
  180. /* endmain */
  181.  
  182. label_do()
  183. {
  184.     register int x;
  185.  
  186.     do_label = NO;
  187.     if (pass == 1) {
  188.     /** add as permanent (and/or relative) */
  189.     if (symenter(label, loc_counter, (rorg) ? 'r' : 'a')
  190.         == ERROR) {
  191.         fatal = YES;
  192.         puts("\007\nsymbol table FULL!\007");
  193.         return ERROR;
  194.     }
  195.     }
  196.     else {                      /* pass == 2 */
  197.     if (x = symsearch(label)) {
  198.         if (symtbl[x]._atr & 4) {           /* redefined */
  199.         err_out(REDEF);
  200.         err_out(NULL);    /* cause the dumping of this error */
  201.         if (symtbl[x]._val != loc_counter) {
  202.         err_out(PHASE);
  203.         err_out(NULL);
  204.         }
  205.         }
  206.     }
  207.     else {
  208.         err_out(UNDEF_SYMBOL);  /* label never defined */
  209.         err_out(NULL);    /* cause the dumping of this error */
  210.     }
  211.     }
  212.     return OK;
  213. }
  214.  
  215. dump_code(typ, cdp, cdl)
  216. int typ;
  217. char *cdp;
  218. int cdl;
  219. {
  220.     register int x, y;
  221.     char buf[85];
  222.     char acode[20];
  223.  
  224.     switch (typ) {
  225.     case CODE:         /* dump all fields, including error stack */
  226.     case DATA:         /* dump line, loc, code, pseudo, op/comments */
  227.     case MSG:
  228.     obj_out(typ, cdp, cdl);
  229.     if (!lstchnl) {
  230.         if (typ == CODE  || typ == MSG)    /* dump remaining op/com */
  231.         if (errchnl && any_errors) err_out(NULL); /* dump errors */
  232.         break;
  233.     }
  234.     if (!cdl) {        /* print loc only if data */
  235.         sprintf(buf, " %4d        ", line_count);
  236.     } else {
  237.         sprintf(buf, " %4d %06lx ", line_count, loc_counter);
  238.     }
  239.     x = 13;
  240.     if (cdl) {
  241.         hex_byt(acode, cdp, cdl);        /* convert raw code to ascii hex */
  242.         for (y = 0; y < (cdl * 2); ) {  /* for each byt in acode */
  243.         buf[x++] = acode[y++];        /* ...move to buf... */
  244.         if (!(y%4)) buf[x++] = ' ';     /* ...if 4th byte add space */
  245.         }
  246.     }
  247.     while (x < 40) buf[x++]    = ' ';      /* pad rest with spaces */
  248.     buf[x] = '\0';
  249.     list_dump(buf);                /* send it */
  250.     if (get_source(buf)) {          /* dump the source */
  251.         list_dump(buf);
  252.     }
  253.     if (typ == DATA) break;         /* let data sender flush */
  254.     goto flush;                /* dump source */
  255.     case MDATA:                 /* dump loc, code, op/comments